package com.tfjybj.itoo.exam.provider.service.impl;


import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.dmsdbj.itoo.tool.base.service.impl.BaseServicePlusImpl;
import com.dmsdbj.itoo.tool.business.ItooResult;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tfjybj.itoo.exam.entity.AccountItemEntity;
import com.tfjybj.itoo.exam.model.AccountItemModel;
import com.tfjybj.itoo.exam.model.AccountItemTemplate;
import com.tfjybj.itoo.exam.model.AddAccountItemModel;
import com.tfjybj.itoo.exam.provider.dao.AccountItemDao;
import com.tfjybj.itoo.exam.provider.service.AccountItemService;
import lombok.extern.slf4j.Slf4j;
import org.jplus.hyberbin.excel.utils.ExcelUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.*;

/**
 * AccountItemService接口实现类
 * ${base}表
 *
 * @author 任晓帅
 * @version 2.0.0
 * @since 2.0.0 2018-11-15 19:40:28
 */

@Slf4j
@Service("accountItemService")
public class AccountItemServiceImpl extends BaseServicePlusImpl<AccountItemDao, AccountItemEntity> implements AccountItemService {

    //region 模板生成
    @Resource
    private AccountItemDao accountItemDao;

    @Resource
    private AccountItemService accountItemService;

    @Override
    public PageInfo<AccountItemEntity> queryByLikeName(String name, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return new PageInfo<>(accountItemDao.queryLikeName(name));
    }
    //endregion

    /* **********************************以下为非模板生成的内容********************************* */


    /**
     * 根据会计科目名字获取数据
     *
     * @param name 会计科目名字
     * @return 会计科目的accountItemModel
     * @author 杨楠
     * @since 2.0.0 2018-11-15 10:35:56
     */


    @Override
    public List<AccountItemModel> queryAccountingSubject(String name) {
        if (name == null || StringUtils.isEmpty(name)) {
            return Collections.emptyList();
        }

        List<AccountItemModel> accountItemlist = accountItemDao.queryAccountingSubjectByName(name);
        if (accountItemlist == null || CollectionUtils.isEmpty(accountItemlist)) {
            return Collections.emptyList();
        }

        List<AccountItemModel> accountItemModels = new ArrayList<>();
        // for (循环变量类型 循环变量名称 : 要被遍历的对象)  循环体
        for (AccountItemModel aAccountinglist : accountItemlist) {
            //重新new一个model，存放查询出来的数据。 java中new一个对象放在循环体里面与外面是有区别的
            AccountItemModel accountItemModel = new AccountItemModel();
            accountItemModel.setKey(aAccountinglist.getTitle());
            accountItemModel.setTitle(aAccountinglist.getTitle());
            accountItemModel.setParentId(aAccountinglist.getParentId());
            accountItemModel.setIsLeaf(aAccountinglist.getIsLeaf());


            List<AccountItemModel> accountingList = accountItemDao.queryAccountingSubjectByPid(aAccountinglist.getKey());
            accountItemModel.setChildren(accountingList);


            accountItemModels.add(accountItemModel);

        }
        return accountItemModels;
    }


    @Override
    public boolean createAccount(List<AddAccountItemModel> accountItemModels) {
        List<AddAccountItemModel> models = resolve(accountItemModels);
        List<AccountItemEntity> entities = new ArrayList<>();

        for (AddAccountItemModel model : models) {
            AccountItemEntity entity = new AccountItemEntity();
            BeanUtils.copyProperties(model, entity);

            if (StringUtils.isEmpty(entity.getParentId())) {
                entity.setParentId("0");
            }
            if (StringUtils.isEmpty(entity.getId())) {
                entity.setId(IdWorker.getIdStr());
            }
            entities.add(entity);
        }
        return accountItemService.saveBatch(entities);

    }

    @Override
    public List<AccountItemEntity> queryTreeModel() {
        return accountItemDao.queryTreeModel();
    }


    private List<AddAccountItemModel> resolve(List<AddAccountItemModel> accountItemModels) {

        List<AddAccountItemModel> accountItemModelList = new ArrayList<>();
        for (AddAccountItemModel model : accountItemModels) {
            model.setKey(IdWorker.getIdStr());
            if (model.getChildren() != null && model.getChildren().size() > 0) {
                if (model.getChildren().get(0) == null) {
                    model.setChildren(null);
                }
            }
            if (!(CollectionUtils.isEmpty(model.getChildren()))) {
                for (AddAccountItemModel accountItemModel : model.getChildren()) {
                    accountItemModel.setParentId(model.getKey());
                }
                accountItemModelList.addAll(resolve(model.getChildren()));
            }
            accountItemModelList.add(model);
        }
        return accountItemModelList;
    }


    @Override
    public ItooResult importByExcel(MultipartFile multipartFile, HttpServletRequest request, HttpServletResponse response, String operator) {

        response.setContentType("UTF-8");

        Map failAgre = new HashMap();
        int failLog = 0;
        try {
            //校验文件是否存在
            String fileName = multipartFile.getOriginalFilename();
            if (fileName == null) {
                log.error("导入失败，文件不存在");
                return ItooResult.build(ItooResult.FAIL, "导入失败，文件不存在");
            }
            Map<Serializable, Serializable> map = new HashMap<>(4);
            map.put("sheetName", "会计子科目");
            map.put("Class", AccountItemTemplate.class);
            List<AccountItemTemplate> accountItemTemplateList = ExcelUtil.importExcel(Objects.requireNonNull(fileName), map, request, response);
            if (accountItemTemplateList.size() == 0) {
                return ItooResult.build(ItooResult.FAIL, "导入失败，文件内容为空");
            }

            AccountItemEntity accountItemEntity = new AccountItemEntity();
            String initialGrandParent = accountItemTemplateList.get(0).getGrandParent();
            String initialGrandParentId = IdWorker.getIdStr();
            accountItemEntity.setParentId("0");
            accountItemEntity.setIsLeaf(0);
            accountItemEntity.setId(initialGrandParentId);
            accountItemEntity.setName(initialGrandParent);
            accountItemEntity.setOperator(operator);
            accountItemService.save(accountItemEntity);

            AccountItemEntity parentEntity = new AccountItemEntity();
            String initialParent = accountItemTemplateList.get(0).getParent();
            String initialParentId = IdWorker.getIdStr();

            parentEntity.setName(initialParent);
            parentEntity.setId(initialParentId);
            parentEntity.setOperator(operator);
            parentEntity.setParentId(initialGrandParentId);
            parentEntity.setIsLeaf(0);
            accountItemService.save(parentEntity);

            for (AccountItemTemplate template : accountItemTemplateList) {
                if (!(initialParent.equals(template.getParent()))) {

                    initialParent = template.getParent();
                    initialParentId = IdWorker.getIdStr();
                    parentEntity.setName(initialParent);
                    parentEntity.setId(initialParentId);
                    parentEntity.setOperator(operator);
                    parentEntity.setParentId(initialGrandParentId);
                    parentEntity.setIsLeaf(0);
                    accountItemService.save(parentEntity);

                    //存储二级节点
                    AccountItemEntity entity = new AccountItemEntity();
                    entity.setName(template.getSon());
                    entity.setId(IdWorker.getIdStr());
                    entity.setIsLeaf(1);
                    entity.setParentId(initialParentId);
                    entity.setOperator(operator);
                    accountItemService.save(entity);
                } else {

                    //存储二级节点
                    AccountItemEntity entity = new AccountItemEntity();
                    entity.setName(template.getSon());
                    entity.setId(IdWorker.getIdStr());
                    entity.setIsLeaf(1);
                    entity.setParentId(initialParentId);
                    entity.setOperator(operator);
                    accountItemService.save(entity);
                }


            }

        } catch (Exception e) {
            return ItooResult.build(ItooResult.FAIL, "导入数据异常！", e);
        }

        return ItooResult.build(ItooResult.SUCCESS, "导入成功");
    }

    /**
     * 添加一条分类
     *
     * @param addAccountItemModel
     * @author duyu
     * @since 2019年6月19日
     */
    @Transactional
    @Override
//    @CacheEvict(value = {"queryAccountingSubjectByPid", "queryAccountingSubjectByName"}, allEntries = true)
    public AccountItemEntity createAccountItemNode(AddAccountItemModel addAccountItemModel) {
        AccountItemEntity accountItemEntity = new AccountItemEntity();
        BeanUtils.copyProperties(addAccountItemModel, accountItemEntity);

        if (StringUtils.isEmpty(accountItemEntity.getParentId())) {
            accountItemEntity.setParentId("0");
        }
        if (StringUtils.isEmpty(accountItemEntity.getId())) {
            accountItemEntity.setId(IdWorker.getIdStr());
        }
        //查询level
        AccountItemEntity classifyEntity = this.getById(addAccountItemModel.getParentId());
        if (classifyEntity == null || "0".equals(classifyEntity.getParentId())) {
            accountItemEntity.setLevel(0);
        } else {
            accountItemEntity.setLevel(classifyEntity.getLevel() + 1);
        }
        //设置当前节点为叶子节点
        accountItemEntity.setIsLeaf(1);

        // 修改该节点的父节点 is_leaf 非叶子节点
        AccountItemEntity pEntity = accountItemDao.selectById(accountItemEntity.getParentId());
        if (pEntity != null) {
            pEntity.setIsLeaf(0);
            this.updateById(pEntity);
        }

        // 插入节点
        this.insert(accountItemEntity);
        return accountItemEntity;
    }


    /**
     * 重写 updatebyId
     * @param entity
     * @return
     * @author duyu
     * @since 2019年6月30日
     */
    @Override
    @CacheEvict(value = {"queryAccountingSubjectByPid", "queryAccountingSubjectByName"}, allEntries = true)
    public boolean updateById(AccountItemEntity entity) {

        int flag = accountItemDao.updateById(entity);
        if (flag > 0) {
            return true;
        }
        return false;
    }

    /**
     * 重写 inster
     * @param entity
     * @return
     * @author duyu
     * @since 2019年6月30日
     */
    @Override
    @CacheEvict(value = {"queryAccountingSubjectByPid", "queryAccountingSubjectByName"}, allEntries = true)
    public int insert(AccountItemEntity entity) {
        return accountItemDao.insert(entity);
    }

}
